package pATT.bNEdit.gui;

import java.awt.Color;
import java.awt.Cursor;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseEvent;

import javax.swing.SwingUtilities;

import pATT.bNEdit.jgraph.org.jgraph.JGraph;
import pATT.bNEdit.jgraph.org.jgraph.graph.BasicMarqueeHandler;
import pATT.bNEdit.jgraph.org.jgraph.graph.DefaultGraphCell;



/**
 * <p>Title: BNEdit</p>
 * <p>Description: Bayesian Network Editor</p>
 * <p>Copyright: Copyright (c) 2004</p>
 * <p>Company: </p>
 * @author Martin Blech && Luciana Zavaleta
 * @version 1.0
 */

public class BNMarqueeHandler extends BasicMarqueeHandler {
  private Point start = null;
  private Point current = null;
  private JGraph graph;
  private NetView editor;
  private DefaultGraphCell cell, firstCell;
  private boolean moved;

  public BNMarqueeHandler(JGraph graph, NetView editor) {
    this.graph = graph;
    this.editor = editor;
  }

  public boolean isForceMarqueeEvent(MouseEvent e) {
    // Wants to Display the PopupMenu
    if (SwingUtilities.isRightMouseButton(e))
      return true;
    // Find and Remember Port
    cell = getCellAt(e.getPoint());
    // If Port Found and in ConnectMode (=Ports Visible)
    if (cell != null && editor.getMode()==editor.getConstArc())
      return true;

    if (editor.getMode()==editor.getConstNode() &&
        SwingUtilities.isLeftMouseButton(e))
      return true;
    // Else Call Superclass
    return super.isForceMarqueeEvent(e);
  }


  // Returns the Cell at the specified Position
  public DefaultGraphCell getCellAt(Point point) {
    // Scale from Screen to Model
    Point tmp = (Point) graph.fromScreen(new Point(point));
    // Find a Port View in Model Coordinates and Remember
    return (DefaultGraphCell) graph.getFirstCellForLocation(tmp.x, tmp.y);
  }

  public void mousePressed(final MouseEvent e) {
    // If Right Mouse Button
    if (SwingUtilities.isRightMouseButton(e)) {
      // Scale From Screen to Model
//      Point l = (Point) graph.fromScreen(e.getPoint());
      // Find Cell in Model Coordinates
//      Object c = graph.getFirstCellForLocation(l.getX(),l.getY());
      if (cell!=null){
           if (editor.isEditorType()){
             // Create PopupMenu for the Cell in Edit Type
             if (cell.getUserObject() instanceof String){
               editor.createEditPopupMenu( (String) cell.getUserObject());
               // Display PopupMenu
               editor.processMouseEvent(e);
             }
           }
           else{
               editor.createRunPopupMenu( (String) cell.getUserObject());
               // Display PopupMenu
               editor.processMouseEvent (e);
           }
      }
    } // Else if in ConnectMode and Remembered Port is Valid
    else
     if (cell != null && !e.isConsumed() &&
           editor.getMode()==editor.getConstArc()) {
           // Remember Start Location
          start = (Point)graph.toScreen(e.getPoint());
          // Remember First Port
          firstCell = cell;
          // Consume Event
          e.consume();
     }
     else
     if (editor.getMode()==editor.getConstNode()) {
        moved = false;
     } else
      // Call Superclass
      super.mousePressed(e);
  }

  public void mouseDragged(MouseEvent e) {
    moved = true;
    // If remembered Start Point is Valid
    if (start != null && !e.isConsumed()) {
      // Fetch Graphics from Graph
      Graphics g = graph.getGraphics();
      // Xor-Paint the old Connector (Hide old Connector)
      paintConnector(Color.black, graph.getBackground(), g);
      // Reset Remembered Port
      cell = getCellAt(e.getPoint());
      // If Port was found then Point to Port Location
      if (cell != null)
        current = (Point) graph.toScreen(e.getPoint());
        // Else If no Port found Point to Mouse Location
      else
        current = (Point) graph.snap(e.getPoint());
        // Xor-Paint the new Connector
      paintConnector(graph.getBackground(), Color.black, g);
      // Consume Event
      e.consume();
    }
    // Call Superclass
    super.mouseDragged(e);
  }

  public void mouseReleased(MouseEvent e) {
    // If Valid Event, Current and First Port
    if (e != null && !e.isConsumed() && cell != null &&
        firstCell != null && firstCell != cell) {
      // Fetch the Underlying Source Port
      String source = (String)firstCell.getUserObject();
      // Fetch the Underlying Target Port
      String target = (String)cell.getUserObject();
      // Then Establish Connection
      editor.addLink(source, target);
      editor.resetMode();
      // Consume Event
      e.consume();
    } else {
      // Else Repaint the Graph
      graph.repaint();
    }
    // Reset Global Vars
    firstCell = cell = null;
    start = current = null;
    if (editor.getMode()==editor.getConstNode() &&
        SwingUtilities.isLeftMouseButton(e) && !moved) {
      editor.addVariable(e.getPoint());
      editor.resetMode();
    }
    // Call Superclass
    super.mouseReleased(e);
  }

  void paintConnector(Color fg, Color bg, Graphics g) {
    // Set Foreground
    g.setColor(fg);
    // Set Xor-Mode Color
    g.setXORMode(bg);
    // If Valid First Port, Start and Current Point
    if (firstCell != null && start != null &&
        current != null) {
      // Then Draw A Line From Start to Current Point
      g.drawLine(start.x, start.y, current.x, current.y);
    }
  }

  public void mouseMoved(MouseEvent e) {
    // Check Mode and Find Port
    if (e != null && getCellAt(e.getPoint()) != null &&
        !e.isConsumed() && graph.isPortsVisible()) {
      // Set Cusor on Graph (Automatically Reset)
      graph.setCursor(new Cursor(Cursor.HAND_CURSOR));
      // Consume Event
      e.consume();
    }
    // Call Superclass
    super.mouseReleased(e);
  }


}


